#pragma once
# include <vector>
# include <thread>
# include <shared_mutex>
# include <functional>
# include <wtypes.h>

class IMMDevice;
class IPropertyStore;
class IAudioClient;
class IAudioRenderClient;
class IAudioCaptureClient;

# define BUFFER_TIME_100NS (5 * 10000000)

# define AUDIO_CAPTURE_START_ERROR 201

class _declspec(dllexport) AudioCapture {
public:
	AudioCapture();
	const wchar_t* getName() const;
	int getSampleRate() const;
	int startCapture();
	void stopCapture();
	~AudioCapture();

	std::function<void(uint8_t* _data, size_t _sample_count, size_t _sample_size)> captureCallback = nullptr;

	int static enumCaptureToVector(std::vector<AudioCapture*>*& _audioCaptureVector);
	void static releaseCaputreFromVector(std::vector<AudioCapture*>*& _audioCaptureVector);
private:
	IMMDevice* m_device = nullptr;
	IAudioClient* m_audio_client = nullptr;
	IAudioCaptureClient* m_capture_client = nullptr;
	std::thread* m_capture_thread = nullptr;
	HANDLE m_audio_samples_ready_event = nullptr;
	wchar_t* m_name = nullptr;
	bool m_alive = false;
	bool m_use_device_ts = false;

	size_t m_sample_size = 0;
	int m_sample_rate = 0;

	std::shared_mutex* m_mutex = nullptr;

	void setName(LPWSTR _name, size_t _size);	
	void init();

	void capture();
};
